<template>
  <div class="project-wayline-wrapper h-full">
    <a-spin :spinning="loading" :delay="300" tip="downloading" size="large">
      <div class="flex flex-col h-full">
        <div class="titlebar flex justify-between items-center px-3">
          <span>航线库</span>
          <a-upload
            v-if="importVisible"
            name="file"
            :multiple="false"
            :before-upload="beforeUpload"
            :show-upload-list="false"
            :customRequest="uploadFile"
          >
            <a-button type="primary" style="color: white">
              导入
              <SelectOutlined />
            </a-button>
          </a-upload>
        </div>
        <div>
          <div class="flex px-2 py-2 gap-2">
            <div class="select-box">
              <el-tree-select
                ref="treeSelect"
                :accordion="true"
                v-model="droneModelKeys"
                :data="droneOptions"
                :node-key="nodeKey"
                :default-expand-all="false"
                :highlight-current="true"
                :current-node-key="currentModelKey"
                @node-click="handleNodeClick"
              />
            </div>

            <div class="time-box flex gap-1 justify-center items-center cursor-pointer" @click="toggleOrder">
              <span>时间倒叙</span>
              <div class="flex flex-col items-center justify-center">
                <el-icon :class="{ 'active text-white': isAscending }"><ArrowUpBold /></el-icon>
                <el-icon :class="{ 'active text-white': !isAscending }"><ArrowDownBold /></el-icon>
              </div>
            </div>
            <div @click="toggleSearch" class="search-box flex justify-center items-center">
              <img src="@/assets/icons/search.svg" alt="" />
            </div>
          </div>
          <div v-if="showContent" class="px-2">
            <el-input
              v-model="searchParams.key"
              placeholder="请输入路线名称"
              @keypress.enter="getWaylines({ key: searchParams.key })"
            />
          </div>
        </div>
        <div class="scrollbar flex-1 pb-3">
          <div id="data" class="height-100 uranus-scrollbar" v-if="waylinesData.data.length !== 0" @scroll="onScroll">
            <div v-for="wayline in waylinesData.data" :key="wayline.id">
              <div
                class="wayline-panel px-3 hover:bg-[#f5f5f550] hover:border-[1px] hover:border-[#e6e6e6]"
                :class="{ selected: selectedWaylineId === wayline.id }"
                @click="selectRoute(wayline)"
              >
                <div class="title flex justify-between items-center">
                  <a-tooltip :title="wayline.name">
                    <div class="flex-1 truncate">
                      {{ wayline.name }}
                    </div>
                  </a-tooltip>

                  <div class="fz20">
                    <a-dropdown>
                      <a style="color: white">
                        <EllipsisOutlined />
                      </a>
                      <template #overlay>
                        <a-menu theme="dark" class="more" style="background: #3c3c3c">
                          <a-menu-item @click="downloadWayline(wayline.id, wayline.name)">
                            <span>下载</span>
                          </a-menu-item>
                          <a-menu-item @click="showWaylineTip(wayline.id)">
                            <span>删除</span>
                          </a-menu-item>
                        </a-menu>
                      </template>
                    </a-dropdown>
                  </div>
                </div>
                <div class="flex gap-2 items-center" style="color: hsla(0, 0%, 100%, 0.65)">
                  <div class="flex flex-1 gap-1 items-center max-w-20">
                    <UserOutlined />
                    <a-tooltip :title="wayline.user_name">
                      <div class="flex-1 truncate">
                        {{ wayline.user_name }}
                      </div>
                    </a-tooltip>
                  </div>
                  <div class="flex gap-1 items-center">
                    <RocketOutlined />
                    <span>{{ DEVICE_NAME[wayline.drone_model_key] }}</span>
                  </div>
                  <div class="flex gap-1 items-center">
                    <CameraFilled />
                    <span v-for="(payload, id) in wayline.payload_model_keys" :key="id">
                      {{ DEVICE_NAME[payload] }}
                    </span>
                  </div>
                </div>
                <div class="mt5 ml10" style="color: hsla(0, 0%, 100%, 0.35)">
                  <span class="mr10">更新时间 {{ new Date(wayline.update_time).toLocaleString() }}</span>
                </div>
              </div>
            </div>
          </div>
          <div v-else>
            <a-empty :image-style="{ height: '60px', marginTop: '60px' }" />
          </div>
          <a-modal
            v-model:visible="deleteTip"
            width="450px"
            :closable="false"
            :maskClosable="false"
            centered
            :okButtonProps="{ danger: true }"
            @ok="deleteWayline"
          >
            <p class="pt10 pl20" style="height: 50px">路线文件一旦删除就无法恢复。继续？</p>
            <template #title>
              <div class="flex-row flex-justify-center">
                <span>删除</span>
              </div>
            </template>
          </a-modal>
        </div>
      </div>
    </a-spin>
  </div>
</template>

<script lang="ts" setup>
import { downloadFile, convertTime } from 'sunrise-utils'
import { reactive } from '@vue/reactivity'
import { message } from 'ant-design-vue'
import { onMounted, onUpdated, ref, onBeforeUnmount } from 'vue'
import { deleteWaylineFile, downloadWaylineFile, getWaylineFiles, importKmzFile } from '@/api/wayline'
import { ELocalStorageKey, ERouterName } from '@/types'
import { EllipsisOutlined, RocketOutlined, CameraFilled, UserOutlined, SelectOutlined } from '@ant-design/icons-vue'
import { DEVICE_NAME } from '@/types/device'
import { useMyStore } from '@/store'
import {
  ElTreeSelectInstance,
  WaylineFile,
  WayLineFile,
  droneOptions,
  TemplateTypes,
  PointType,
  WaylineDataInfo,
  ITemplatePointInfo
} from '@/types/wayline'
import { IPage } from '@/api/http/type'
import { getRoot } from '@/root'
import useGMapManage from '@/hooks/use-g-map'
import { sessionStorage } from '@/utils/storage'
import * as turf from '@turf/turf'
import { ar } from 'element-plus/es/locale'
import { parseCoordinates, processPolygonData } from '/@/utils/map'
const isAscending = ref(false)
const toggleOrder = async () => {
  const time = `update_time ${isAscending.value ? 'desc' : 'asc'}`
  await getWaylines({ order_by: time })
  isAscending.value = !isAscending.value
}
const selectedWaylineId = ref('')
const loading = ref(false)
const store = useMyStore()
const pagination: IPage = {
  page: 1,
  total: -1,
  page_size: 10
}
const nodeKey = 'value'
const currentModelKey = ref(0)
const treeSelect = ref<ElTreeSelectInstance | null>(null)

const handleNodeClick = async ({ value, children, label }: { value: string; label?: string; children?: any[] }) => {
  if (label === '全部机型') {
    await getWaylines()
  }
  await getWaylines({ drone_model_keys: value })
  droneModelKeys.value = value
  treeSelect.value!.blur()
}
const droneModelKeys = ref('全部机型')

const waylinesData = reactive({
  data: [] as WayLineFile<TemplateTypes[]>[]
})
const searchParams = ref({
  key: ''
})

const root = getRoot()
const workspaceId = sessionStorage.get(ELocalStorageKey.WorkspaceId)!
const deleteTip = ref(false)
const deleteWaylineId = ref<string>('')
const canRefresh = ref(true)
const importVisible = ref<boolean>(root.$router.currentRoute.value.name === ERouterName.WAYLINE)
const height = ref()
const showContent = ref(false)

const toggleSearch = async () => {
  showContent.value = !showContent.value
}
onMounted(async () => {
  await getWaylines()
})

const getWaylines = async (params: any = {}) => {
  if (!canRefresh.value) {
    return
  }
  const newParams = { page: params.page || 1, page_size: params.page_size || 10, order_by: 'update_time desc', ...params }
  canRefresh.value = false
  loading.value = true
  await getWaylineFiles(workspaceId, newParams)
    .then((res) => {
      if (res.code !== 1) {
        return
      }
      console.log(params, '===========')
      if (params.scroll) {
        waylinesData.data = [...waylinesData.data, ...res.data.list]
        pagination.total = res.data.pagination.total
        pagination.page = res.data.pagination.page
      } else {
        console.log('搜索')
        waylinesData.data = []
        pagination.total = 0
        pagination.page = 1
        waylinesData.data = res.data.list
        pagination.total = res.data.pagination.total
        pagination.page = res.data.pagination.page
      }

      // waylinesData.data = [...waylinesData.data, ...res.data.list]
      // pagination.total = res.data.pagination.total
      // pagination.page = res.data.pagination.page
    })
    .finally(() => {
      loading.value = false
      canRefresh.value = true
    })
}

function showWaylineTip(waylineId: string) {
  deleteWaylineId.value = waylineId
  deleteTip.value = true
}

function deleteWayline() {
  deleteWaylineFile(workspaceId, deleteWaylineId.value).then((res) => {
    if (res.code === 1) {
      message.success('Wayline file deleted')
    }
    deleteWaylineId.value = ''
    deleteTip.value = false
    pagination.total = 0
    pagination.page = 1
    waylinesData.data = []
    getWaylines()
  })
}

function downloadWayline(waylineId: string, fileName: string) {
  loading.value = true
  downloadWaylineFile(workspaceId, waylineId)
    .then((res) => {
      downloadFile(res, fileName + '.kmz')
    })
    .finally(() => {
      loading.value = false
    })
}

/**
 * 提交航线信息到store
 * @param type 航线类型
 * @param data 航线数据
 */
const commitWaylineInfo = (type: 0 | 1 | 2, data: WaylineDataInfo) => {
  const mutationMap = {
    0: 'SET_SINGLE_WAYLINE_DATA_INFO',
    1: 'SET_TOTAL_WAYLINE_DATA_INFO',
    2: 'SET_INCLINE_WAYLINE_DATA_INFO'
  }
  store.commit(mutationMap[type], data)
}

// ==================== 处理逻辑模块 ====================
/**
 * 处理基础航线（type 0）
 */
const handleBasicRoute = (wayline: WayLineFile<TemplateTypes[]>, startPoint: PointType) => {
  const wayLines = wayline.templatePointInfo.map((point) => {
    const [Lon, Lat] = point?.Point.coordinates.split(',')
    return { Lon: +Lon, Lat: +Lat, height: +point.height }
  })
  wayLines.unshift(startPoint)
  console.log(wayLines, 'wayLines')
  useGMapManage.renderLine(wayLines)

  commitWaylineInfo(0, {
    distance: wayline.distance.toFixed(2),
    duration: convertTime(wayline.duration, 'en'),
    photo_num: wayline.photo_num,
    pointNun: wayline.waylinePointInfo?.length
  })
}
/**
 * 处理正射航线（type 1）
 */
const handleOrthoRoute = (wayline: WayLineFile<TemplateTypes[]>, startPoint: PointType) => {
  const wayLines = wayline.orthophotoPointInfo!.map((point) => {
    return { ...parseCoordinates(point.Point.coordinates), height: +point.executeHeight }
  })
  wayLines.unshift(startPoint)
  const { polygon, coordinates } = processPolygonData(wayline.templatePointInfo)
  const area = turf.area(polygon).toFixed(2)

  commitWaylineInfo(1, {
    area,
    distance: wayline.distance.toFixed(2),
    duration: convertTime(wayline.duration, 'en'),
    photo_num: wayline.photo_num
  })
  useGMapManage.initPolygon(wayLines, coordinates)
}
/**
 * 处理倾斜摄影（type 2）
 */
const handleInclineRoute = (wayline: WayLineFile<TemplateTypes[]>, startPoint: PointType) => {
  const { polygon, coordinates } = processPolygonData(wayline.templatePointInfo)
  const wayLines = wayline.inclinePointInfo[0].wailinePointList!.map((point) => {
    return { ...parseCoordinates(point.Point.coordinates), height: +point.executeHeight }
  })
  wayLines.unshift(startPoint)

  commitWaylineInfo(2, {
    area: turf.area(polygon).toFixed(2),
    distance: wayline.distance.toFixed(2),
    duration: convertTime(wayline.duration, 'en'),
    photo_num: wayline.photo_num
  })

  // 提交额外倾斜摄影数据
  store.commit('SET_INCLINE_POINT_INFO', wayline.inclinePointInfo)
  store.commit('SET_INCLINE_INFO', {
    index: 1,
    total: Object.keys(wayline.inclinePointInfo).length,
    data: {
      distance: wayline.inclinePointInfo[0].distance.toFixed(2),
      duration: convertTime(wayline.inclinePointInfo[0].duration, 'en'),
      photo_num: wayline.inclinePointInfo[0].photoNum
    }
  })

  useGMapManage.initPolygon(wayLines, coordinates)
}

function selectRoute(wayline: WayLineFile<TemplateTypes[]>) {
  const type = wayline.template_types[0]
  store.commit('SET_SELECT_WAYLINE_INFO', wayline)

  // 初始化起降点
  const [startLat, startLon] = wayline.takeOffRefPoint.split(',')
  const startPoint = {
    Lon: +startLon,
    Lat: +startLat,
    height: type === 1 ? +wayline.templatePointInfo[0].ellipsoidHeight : 0
  }

  store.commit('SET_IS_SHOW_CONTROL_WAYLINE', true)

  // 路由处理
  const routeHandlers = {
    0: () => handleBasicRoute(wayline, startPoint),
    1: () => handleOrthoRoute(wayline, startPoint),
    2: () => handleInclineRoute(wayline, startPoint)
  }

  routeHandlers[type]()
  selectedWaylineId.value = wayline.id
}

// 卸载
onBeforeUnmount(() => {
  useGMapManage.clearLine()
  store.commit('SET_IS_SHOW_CONTROL_WAYLINE', false)

  if (store.state.showWaylineType === 1) {
    store.commit('SET_SINGLE_WAYLINE_DATA_INFO', {
      distance: '',
      duration: '',
      photo_num: '',
      pointNun: ''
    })
  }

  if (store.state.showWaylineType === 2) {
    store.commit('SET_TOTAL_WAYLINE_DATA_INFO', {
      area: '',
      distance: '',
      duration: '',
      photo_num: ''
    })
  }
  if (store.state.showWaylineType === 3) {
    store.commit('SET_INCLINE_WAYLINE_DATA_INFO', {
      distance: '',
      duration: '',
      photo_num: '',
      area: ''
    })
  }
})

function onScroll(e: any) {
  const element = e.srcElement
  if (
    element.scrollTop + element.clientHeight >= element.scrollHeight - 5 &&
    Math.ceil(pagination.total / pagination.page_size) > pagination.page &&
    canRefresh.value
  ) {
    pagination.page++
    getWaylines({ scroll: true, page: pagination.page })
  }
}

interface FileItem {
  uid: string
  name?: string
  status?: string
  response?: string
  url?: string
}

interface FileInfo {
  file: FileItem
  fileList: FileItem[]
}
const fileList = ref<FileItem[]>([])

function beforeUpload(file: FileItem) {
  fileList.value = [file]
  loading.value = true
  return true
}
const uploadFile = async () => {
  fileList.value.forEach(async (file: FileItem) => {
    const fileData = new FormData()
    fileData.append('file', file, file.name)
    await importKmzFile(workspaceId, fileData)
      .then((res) => {
        if (res.code === 1) {
          message.success(`${file.name} 文件上传成功`)
          canRefresh.value = true
          pagination.total = 0
          pagination.page = 1
          waylinesData.data = []
          getWaylines()
        }
        if (res.code === 0) {
          message.error(`${res.message || '文件上传失败'}`)
        }
      })
      .finally(() => {
        loading.value = false
        fileList.value = []
      })
  })
}
</script>

<style lang="scss" scoped>
.wayline-panel {
  background: rgba(219, 219, 219, 0.06);
  height: vh(100);
  font-size: 13px;
  border-radius: 6px;
  cursor: pointer;
  border: 1px solid rgba(219, 219, 219, 0.4);

  .title {
    font-size: px2font(16);
    font-weight: 400;
    text-align: left;
    color: #ffffff;
    display: flex;
    flex-direction: row;
    align-items: center;
    font-weight: bold;
  }
}

.titlebar {
  height: vh(50);
  border-bottom: 1px solid #4f4f4f;
  font-weight: 450;
}

.scrollbar {
  overflow-y: auto;
}

.uranus-scrollbar {
  overflow: auto;
  scrollbar-width: thin;
  scrollbar-color: #c5c8cc transparent;
}

.select-box {
  width: vw(120);
  height: vh(36);
  border-radius: 2px;

  :deep(.el-select) {
    height: 100%;

    .el-select__wrapper {
      min-height: 100%;
      height: 100%;
    }
  }
}

.time-box {
  width: vw(120);
  height: vh(36);
  background-color: #dbdbdb40;
  border-radius: 2px;
  font-size: px2font(16);
  font-weight: 400;
  color: #ffffff;

  &:hover {
    border: 1px solid #dbdbdb;
    border-radius: 4px;
  }
}

.search-box {
  width: vw(36);
  height: vh(36);
  background-color: #dbdbdb40;
  border-radius: 2px;
  font-size: px2font(16);
  font-weight: 400;
  color: #ffffff;
  cursor: pointer;

  &:hover {
    border: 1px solid #dbdbdb;
    border-radius: 4px;
  }
}

.active {
  color: #333;
  /* 或者其他你想要的高亮颜色 */
}

:deep(.ant-spin-nested-loading) {
  height: 100%;

  .ant-spin-container {
    height: 100%;
  }
}

.selected {
  background-color: #1890ff;
  /* 选中时的背景颜色 */
  color: white;
  /* 选中时的文字颜色 */
}
.el-icon {
  height: 10px !important;
}
</style>
